/**
 * @file message.c
 *
 */

/*********************
*      INCLUDES
*********************/
#include "lv_watch.h"

#if USE_LV_WATCH_MESSAGE != 0

/*********************
*      DEFINES
*********************/
#define MESSAGE_OFFSET 2 /* sms, wechat */

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/
static void message_prepare_destory(lv_obj_t * activity_obj);
static lv_message_obj_ext_t * message_get_ext(void);
static void message_no_notification_create(lv_obj_t * obj);
static void message_ui_update(void);
static void message_list_create(lv_obj_t * obj);
static void message_detail_prepare_destory(lv_obj_t * activity_obj);
static lv_obj_t * message_detail_create(lv_obj_t * activity_obj);
static void message_detail_content_create(lv_obj_t * obj);
static void message_msg_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void message_list_content_create(void);
static void message_del_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void message_delete_create(void);
static void message_ll_init(void);
static void message_ll_destory(void);
static void message_ll_item_add(message_msg_info_t * info);
static void message_ll_item_del(uint32_t index);
static uint32_t message_ll_get_node_count(void);
static message_msg_info_t * message_ll_get_item_info(uint32_t index);
static lv_coord_t message_get_text_length(lv_obj_t * label, char * text, lv_font_t * font);
static uint32_t message_get_character_count(lv_obj_t * label, char * text, lv_font_t * font, lv_coord_t length_max);
static char * message_adjust_display_data(char * data, uint32_t length);
static void message_update_ui_task_handle(lv_task_t * task);
static void message_audio_ctrl_callback(AUDIO_CTRL_PRIORITY priority);
static void message_tone_play_onetime_cb(void *para);

/**********************
*  STATIC VARIABLES
**********************/
static lv_ll_t * message_ll = NULL;
static bool display_on = false;
static lv_task_t * message_update_ui_task = NULL;
const void * source[] = {
            (void *)ICON_MESSAGE_SMS_SMALL,
            (void *)ICON_MESSAGE_WECHAT_SMALL,
            (void *)ICON_MESSAGE_SMS_BIG,
            (void *)ICON_MESSAGE_WECHAT_BIG,
};

/**********************
*      MACROS
**********************/

/**********************
 *   GLOBAL FUNCTIONS
 ***********************/
lv_obj_t * message_create(lv_obj_t * activity_obj)
{
    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        _lv_memset_00(&activity_ext, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_MESSAGE;
        activity_ext.create = message_create;
        activity_ext.prepare_destory = message_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) return NULL;
    }

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) return NULL;

    lv_message_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_message_obj_ext_t));
    LV_ASSERT_MEM(ext);
    if(NULL == ext) return NULL;
    ext->list = NULL;
    ext->cont_tip = NULL;
    ext->msg_index = NULL;
    ext->curr_index = 0;

    display_on = false;

    if(NULL == message_ll) {
        message_no_notification_create(obj);
    } else {
        message_list_create(obj);
        message_list_content_create();
        message_delete_create();
    }

    return activity_obj;
}

void message_create_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;
    if(LV_EVENT_CLICKED == e)
    {
        lv_watch_png_cache_all_free();
        lv_obj_t * obj = message_create(NULL);
        LV_ASSERT_MEM(obj);
        if(NULL == obj) return;
    }
}

bool message_display_message_icon_check(void)
{
    return display_on;
}

/**
* new message information
* param (in) msg_info: app_adaptor_new_message_info_t *
* return  void
*/
void app_adaptor_update_message_info_req(app_adaptor_new_message_info_t * msg_info)
{
    printf("%s\n", __FUNCTION__);
    phonebook_contact_t * contact = NULL;
    char * number = NULL;
    number = (char *)lv_mem_alloc(strlen(msg_info->name) + 1);
    memcpy(number,msg_info->name,(strlen(msg_info->name) + 1));
    printf("number is %s in %s\n",number,__FUNCTION__);
    contact = phonebook_get_contact_info(number);
    if (contact)
    {
        lv_mem_free(msg_info->name);
        msg_info->name = (char *)lv_mem_alloc(strlen(contact->contact_name) + 1);
        memcpy(msg_info->name,contact->contact_name,(strlen(contact->contact_name) + 1));
        printf("name is %s in %s\n",msg_info->name,__FUNCTION__);
        lv_mem_free(contact);
    }
    if(AUDIO_CTRL_PRIORITY_8 == Hal_Audio_Manage_Start_Req(AUDIO_CTRL_PRIORITY_8, message_audio_ctrl_callback))
    {
        Hal_NFFS_File_Play_Onetime(AUDIO_MSG, query_current_volume(), message_tone_play_onetime_cb, NULL);
        printf("AUDIO_MSG has been played in %s\n",__FUNCTION__);
    }
    message_ll_item_add(msg_info);
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(true);
    }
    if(NULL == message_update_ui_task) {
        message_update_ui_task = lv_task_create(message_update_ui_task_handle, 0, LV_TASK_PRIO_HIGH, NULL);
    }
}

/**
* delete message information since message deleted by user or message read by user
* param (in) index: uint32_t
* return  void
*/
void app_adaptor_delete_message_info_req(uint32_t index)
{
    printf("%s\n", __FUNCTION__);
    message_ll_item_del(index);
    if(NULL == message_update_ui_task) {
        message_update_ui_task = lv_task_create(message_update_ui_task_handle, 0, LV_TASK_PRIO_HIGH, NULL);
    }
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static void message_prepare_destory(lv_obj_t * activity_obj)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);
    if(ext->msg_index) {
        lv_mem_free(ext->msg_index);
        ext->msg_index = NULL;
    }
    #if USE_LV_WATCH_LAUNCHER2 != 0
    lv_launcher_obj_ext_t * launcherext = lv_obj_get_ext_attr(lv_watch_get_activity_obj(ACT_ID_LAUNCHER));
    if(launcherext->pull_up_start == 1) {
         dial_clock_resume_task();
         launcherext->pull_up_start = 0;
    }
    #endif
    lv_watch_png_cache_all_free();
}

static void message_tone_play_onetime_cb(void *para)
{
    printf("%s has been called\n", __FUNCTION__);
    Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_8);
}

static void message_audio_ctrl_callback(AUDIO_CTRL_PRIORITY priority)
{
    printf("%s\n", __FUNCTION__);
    Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_8);
}

static lv_message_obj_ext_t * message_get_ext(void)
{
    lv_message_obj_ext_t * ext = NULL;
    lv_obj_t * watch_obj = NULL;

    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_MESSAGE);
    if(activity_obj) {
        lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    }
    if(watch_obj) {
        ext = lv_obj_get_ext_attr(watch_obj);
    }
    return ext;
}

static void message_no_notification_create(lv_obj_t * obj)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    lv_obj_t * cont = lv_cont_create(obj, NULL);
    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
    lv_obj_align(cont, obj, LV_ALIGN_IN_TOP_MID, 0, 0);
    #if USE_LV_WATCH_LAUNCHER2 != 0
    lv_launcher_obj_ext_t * launcherext = lv_obj_get_ext_attr(lv_watch_get_activity_obj(ACT_ID_LAUNCHER));
    if(launcherext->pull_up_start == 1){
        lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
        lv_obj_set_click(obj, true);
        launcher_set_pull_up_signal(cont);
    }
    else
    #endif
    {
        lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_style_transp);
        lv_obj_set_click(cont, false);
    }

    lv_obj_t * img = lv_img_create(cont, NULL);
    lv_img_set_src(img, ICON_MESSAGE_NO_NOTIFICATION);
    lv_obj_align(img, cont, LV_ALIGN_CENTER, 0, -(LV_VER_RES / 10));
    lv_obj_set_click(img, false);

    lv_obj_t * label = lv_label_create(cont, NULL);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, LV_HOR_RES / 2);
    lv_label_set_text_id(label, WATCH_TEXT_ID_NO_NOTIFICATION);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(label, cont, LV_ALIGN_CENTER, 0, LV_VER_RES / 10);
    lv_obj_set_click(label, false);

    ext->cont_tip = cont;
}

static void message_ui_update(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_MESSAGE);

    if(activity_obj) {
        lv_obj_t * obj = lv_obj_get_child_back(lv_obj_get_child_back(activity_obj, NULL), NULL);
        lv_message_obj_ext_t * ext = message_get_ext();
        LV_ASSERT_MEM(ext);

        uint32_t msg_cnt = message_ll_get_node_count();
        if(0 == msg_cnt) {
            if(ext->list) {
                lv_obj_del(ext->list);
                ext->list = NULL;
            }
            if(NULL == ext->cont_tip) {
                message_no_notification_create(obj);
            }
        } else {
            if(ext->list) {
                lv_list_clean(ext->list);
            } else {
                if(ext->cont_tip) {
                    lv_obj_del(ext->cont_tip);
                    ext->cont_tip = NULL;
                }
                message_list_create(obj);
            }
            message_list_content_create();
            message_delete_create();
        }
    } else {
        display_on = true;
    }
}
#if USE_LV_WATCH_LAUNCHER2 != 0
static lv_signal_cb_t ancestor_signal = NULL;
static void message_destroy_tab(lv_anim_t * a)
{
    lv_obj_t * activity_obj = a->var;
    message_prepare_destory(activity_obj);
    if(activity_obj) lv_obj_del(activity_obj);
    dial_clock_resume_task();
}

static lv_res_t message_list_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)
{
    lv_obj_t * list = lv_obj_get_parent(scrl);
    lv_obj_t * act_obj = lv_watch_get_activity_obj(ACT_ID_MESSAGE);
    lv_point_t act_pt;
    lv_indev_t * indev = lv_indev_get_act();
    if(lv_obj_get_y(act_obj) == 0) {
        ancestor_signal(scrl, sign, param);
        if(LV_SIGNAL_COORD_CHG == sign) {
            if(indev && lv_page_on_edge(list, LV_PAGE_EDGE_TOP) && lv_indev_get_gesture_dir(indev) == LV_GESTURE_DIR_BOTTOM) {
                lv_indev_get_point(indev, &act_pt);
                lv_obj_set_y(act_obj, act_pt.y);
            }
        }
    } else {
        if(LV_SIGNAL_COORD_CHG == sign) {
            if(indev && lv_indev_get_gesture_dir(indev) == LV_GESTURE_DIR_BOTTOM) {
                lv_indev_get_point(indev, &act_pt);
                lv_obj_set_y(act_obj, act_pt.y);
            }
        }
        else if(LV_SIGNAL_DRAG_END == sign) {
            if(indev && lv_indev_get_gesture_dir(indev) == LV_GESTURE_DIR_BOTTOM) {
                lv_indev_get_point(indev, &act_pt);
                if(act_pt.y > LV_VER_RES / 2) {
                    lv_obj_set_y_animation(act_obj, LV_VER_RES, true, LV_WATCH_OBJ_HIDE_TIME, message_destroy_tab);
                } else {
                    lv_obj_set_y_animation(act_obj, 0, true, LV_WATCH_OBJ_HIDE_TIME, NULL);
                }
            }
        }
    }
    return LV_RES_OK;
}
#endif

static void message_list_create(lv_obj_t * obj)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    lv_obj_t * list = lv_list_create(obj, NULL);
    lv_page_set_edge_flash(list, true);
    lv_obj_add_style(list, LV_LIST_PART_EDGE_FLASH, &lv_watch_cont_opa1);
    lv_obj_add_style(list, LV_LIST_PART_BG, &lv_watch_style_transp);
    lv_list_set_scrollbar_mode(list, LV_SCROLLBAR_MODE_OFF);
    lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES);
    lv_obj_align(list, obj, LV_ALIGN_IN_TOP_MID, 0, 0);
#if USE_LV_WATCH_LAUNCHER2 != 0
    lv_launcher_obj_ext_t * launcherext = lv_obj_get_ext_attr(lv_watch_get_activity_obj(ACT_ID_LAUNCHER));
    if(launcherext->pull_up_start == 1) {
        lv_obj_set_style_local_bg_opa(list, LV_LIST_PART_BG, LV_STATE_DEFAULT, LV_OPA_COVER);
        lv_obj_set_style_local_bg_color(list, LV_LIST_PART_BG, LV_STATE_DEFAULT, LV_COLOR_BLACK);
        if(ancestor_signal == NULL)
            ancestor_signal = lv_obj_get_signal_cb(lv_page_get_scrollable(list));
        lv_obj_set_signal_cb(lv_page_get_scrollable(list), message_list_scrl_signal);
    } else
#endif
        lv_watch_obj_add_element(list);

    ext->list = list;
}

static void message_detail_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static lv_obj_t * message_detail_create(lv_obj_t * activity_obj)
{
    if(NULL == activity_obj) {
        lv_watch_activity_ext_t activity_ext;
        _lv_memset_00(&activity_ext, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_MESSAGE_DETAIL;
        activity_ext.create = message_detail_create;
        activity_ext.prepare_destory = message_detail_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) return NULL;
    }

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) return NULL;

    message_detail_content_create(obj);

    return obj;
}

static void message_detail_content_create(lv_obj_t * obj)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    message_msg_info_t * info = message_ll_get_item_info(ext->curr_index);
    if(NULL == info) return;

    lv_obj_t * cont = lv_cont_create(obj, NULL);
    lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_style_transp);
    lv_cont_set_fit2(cont, LV_FIT_TIGHT, LV_FIT_TIGHT);
    lv_obj_align(cont, obj, LV_ALIGN_IN_TOP_MID, 0, 0);
    lv_obj_set_click(cont, false);

    lv_obj_t * img = lv_img_create(cont, NULL);
    lv_img_set_src(img, source[info->msg_source + MESSAGE_OFFSET]);
    lv_obj_align(img, cont, LV_ALIGN_IN_TOP_MID, 0, LV_VER_RES / 20);
    lv_obj_set_click(img, false);

    lv_obj_t * name_label = lv_label_create(cont, NULL);
    if(MSG_SOURCE_SMS == info->msg_source) {
        lv_obj_set_style_local_text_color(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, WATCH_COLOR_BLUE);
    } else if(MSG_SOURCE_WECHAT == info->msg_source) {
        lv_obj_set_style_local_text_color(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
    }
    lv_obj_set_style_local_text_font(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
    if((LV_HOR_RES * 4 / 5) < message_get_text_length(name_label, info->name, LV_THEME_WATCH_NIGHT_FONT_NORMAL)) {
        lv_label_set_long_mode(name_label, LV_LABEL_LONG_DOT);
        lv_obj_set_width(name_label, LV_HOR_RES * 4 / 5);
    }
    lv_label_set_text(name_label, info->name);
    lv_label_set_align(name_label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(name_label, img, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_VER_RES / 40);
    lv_obj_set_click(name_label, false);

    lv_obj_t * page = lv_page_create(obj, NULL);
    lv_obj_set_size(page, LV_HOR_RES, LV_VER_RES - lv_obj_get_height(img) - lv_obj_get_height(name_label) - LV_VER_RES / 10);
    lv_obj_add_style(page, LV_PAGE_PART_BG, &lv_style_transp);
    lv_page_set_scrollbar_mode(page, LV_SCROLLBAR_MODE_OFF);
    lv_obj_t * content_label = lv_label_create(page, NULL);
    lv_obj_set_style_local_text_font(content_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
    if((LV_HOR_RES * 3 / 5) < message_get_text_length(content_label, info->data, LV_THEME_WATCH_NIGHT_FONT_NORMAL)) {
        lv_label_set_long_mode(content_label, LV_LABEL_LONG_BREAK);
        lv_obj_set_width(content_label, LV_HOR_RES * 3 / 5);
    }
    lv_label_set_text(content_label, info->data);
    lv_label_set_align(content_label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(content_label, page, LV_ALIGN_IN_TOP_MID, 0, 0);
    lv_obj_set_click(content_label, false);
    lv_obj_t * space_cont = lv_cont_create(page, NULL);
    lv_obj_add_style(space_cont, LV_CONT_PART_MAIN, &lv_style_transp);
    lv_obj_set_size(space_cont, LV_HOR_RES * 3 / 5, LV_VER_RES / 4);
    lv_obj_align(space_cont, content_label, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
    lv_obj_set_click(space_cont, false);
    lv_obj_align(page, cont, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_VER_RES / 40);
    lv_watch_obj_add_element(page);
    lv_watch_obj_add_element(lv_page_get_scrl(page));
}

static void message_msg_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED != e) return;

    lv_watch_png_cache_all_free();

    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    ext->curr_index = *(ext->msg_index + lv_obj_get_user_data(btn).user_num);
    lv_obj_t * obj = message_detail_create(NULL);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) return;

    message_ll_item_del(ext->curr_index);
    message_ui_update();
}

static void message_list_content_create(void)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    uint32_t msg_cnt = message_ll_get_node_count();

    if((NULL != ext->list) && (0 < msg_cnt)) {
        lv_obj_t * btn[msg_cnt];
        lv_obj_t * cont;
        lv_obj_t * source_img;
        lv_obj_t * name_label;
        lv_obj_t * content_label;
        message_msg_info_t * node = NULL;
        message_msg_info_t * next_node = NULL;
        uint32_t i = 0;

        if(ext->msg_index) {
            lv_mem_free(ext->msg_index);
            ext->msg_index = NULL;
        }
        ext->msg_index = (uint32_t *)lv_mem_alloc(sizeof(uint32_t) * msg_cnt);
        _lv_memset_00(ext->msg_index, sizeof(uint32_t) * msg_cnt);

        node = (message_msg_info_t *)_lv_ll_get_head(message_ll);
        for(i = 0; i < msg_cnt; i++) {
            next_node = (message_msg_info_t *)_lv_ll_get_next(message_ll, node);
            btn[i] = lv_list_add_btn(ext->list, NULL, NULL);
            lv_btn_set_layout(btn[i], LV_LAYOUT_OFF);
            lv_obj_set_event_cb(btn[i], message_msg_btn_event_cb);
            lv_btn_set_fit2(btn[i], LV_FIT_PARENT, LV_FIT_NONE);
            lv_obj_set_height(btn[i], LV_VER_RES / 2);
            lv_obj_set_style_local_radius(btn[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
            lv_obj_set_style_local_border_width(btn[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1);
            lv_obj_set_style_local_border_color(btn[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
            lv_obj_set_style_local_border_side(btn[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_BORDER_SIDE_BOTTOM);
            lv_obj_set_style_local_radius(btn[i], LV_BTN_PART_MAIN, LV_STATE_FOCUSED, 0);
            lv_obj_set_style_local_border_width(btn[i], LV_BTN_PART_MAIN, LV_STATE_FOCUSED, 1);
            lv_obj_set_style_local_border_color(btn[i], LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_WHITE);
            lv_obj_set_style_local_border_side(btn[i], LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_BORDER_SIDE_BOTTOM);

            cont = lv_cont_create(btn[i], NULL);
            lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_style_transp);
            lv_cont_set_fit2(cont, LV_FIT_TIGHT, LV_FIT_TIGHT);
            lv_cont_set_layout(cont, LV_LAYOUT_ROW_MID);
            lv_obj_set_click(cont, false);

            source_img = lv_img_create(cont, NULL);
            lv_img_set_src(source_img, source[node->msg_source]);
            lv_obj_set_click(source_img, false);

            name_label = lv_label_create(cont, NULL);
            if(MSG_SOURCE_SMS == node->msg_source) {
                lv_obj_set_style_local_text_color(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, WATCH_COLOR_BLUE);
            } else if(MSG_SOURCE_WECHAT == node->msg_source) {
                lv_obj_set_style_local_text_color(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
            }
            lv_obj_set_style_local_text_font(name_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
            if((lv_obj_get_width(btn[i]) / 3) < message_get_text_length(name_label, node->name, LV_THEME_WATCH_NIGHT_FONT_NORMAL)) {
                lv_label_set_long_mode(name_label, LV_LABEL_LONG_DOT);
                lv_obj_set_width(name_label, lv_obj_get_width(btn[i]) / 3);
            }
            lv_label_set_text(name_label, node->name);
            lv_obj_set_click(name_label, false);

            lv_obj_align(cont, btn[i], LV_ALIGN_IN_TOP_MID, 0, lv_obj_get_width(btn[i]) / 10);

            content_label = lv_label_create(btn[i], NULL);
            lv_obj_set_style_local_text_font(content_label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
            lv_label_set_long_mode(content_label, LV_LABEL_LONG_BREAK);
            lv_obj_set_width(content_label, lv_obj_get_width(btn[i]) * 3 / 5);
            if((lv_obj_get_width(btn[i]) * 9 / 5) < message_get_text_length(content_label, node->data, LV_THEME_WATCH_NIGHT_FONT_NORMAL)) {
                uint32_t cnt = message_get_character_count(content_label, node->data, LV_THEME_WATCH_NIGHT_FONT_NORMAL, lv_obj_get_width(btn[i]) * 9 / 5);
                char * tmp = message_adjust_display_data(node->data, cnt);
                lv_label_set_text(content_label, tmp);
                if(tmp) {
                    lv_mem_free(tmp);
                }
            } else {
                lv_label_set_text(content_label, node->data);
            }
            lv_label_set_align(content_label, LV_LABEL_ALIGN_CENTER);
            lv_obj_align(content_label, cont, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
            lv_obj_set_click(content_label, false);

            #if USE_LV_WATCH_LAUNCHER2 != 0
            lv_launcher_obj_ext_t * launcherext = lv_obj_get_ext_attr(lv_watch_get_activity_obj(ACT_ID_LAUNCHER));
            if(launcherext->pull_up_start == 0)
            #endif
                lv_watch_obj_add_element(btn[i]);
            lv_watch_set_free_num(btn[i], i);
            *(ext->msg_index + i) = node->msg_index;

            node = next_node;
        }
    }
}

static void message_del_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED != e) return;

    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    message_ll_destory();

    lv_obj_t * obj = lv_obj_get_parent(ext->list);
    lv_obj_del(ext->list);
    ext->list = NULL;

    if(NULL == ext->cont_tip) {
        message_no_notification_create(obj);
    }
}

static void message_delete_create(void)
{
    lv_message_obj_ext_t * ext = message_get_ext();
    LV_ASSERT_MEM(ext);

    if((NULL != ext->list) && (0 < message_ll_get_node_count())) {
        lv_obj_t * btn = lv_list_add_btn(ext->list, NULL, NULL);
        lv_obj_set_style_local_bg_opa(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 0);
        lv_btn_set_layout(btn, LV_LAYOUT_OFF);
        lv_btn_set_fit2(btn, LV_FIT_PARENT, LV_FIT_NONE);
        lv_obj_set_height(btn, LV_VER_RES / 2);

        lv_obj_t * btn_del = lv_btn_create(btn, NULL);
        lv_btn_set_layout(btn_del, LV_LAYOUT_OFF);
        lv_obj_set_style_local_radius(btn_del, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
        lv_obj_set_event_cb(btn_del, message_del_btn_event_cb);
        if(LV_VER_RES < LV_HOR_RES) {
            lv_obj_set_size(btn_del, LV_HOR_RES * 3, LV_HOR_RES * 3);
        } else {
            lv_obj_set_size(btn_del, LV_VER_RES * 3, LV_VER_RES * 3);
        }
        lv_obj_align(btn_del, btn, LV_ALIGN_IN_TOP_MID, 0, LV_VER_RES * 3 / 10);

        lv_obj_t * label = lv_label_create(btn_del, NULL);
        lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
        lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_NORMAL);
        lv_label_set_text_id(label, WATCH_TEXT_ID_DELETE_ALL);
        lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
        lv_obj_align(label, btn_del, LV_ALIGN_IN_TOP_MID, 0, LV_VER_RES / 20);
        lv_obj_set_click(label, false);

        lv_watch_obj_add_element(btn_del);
        lv_watch_obj_add_element(btn);
    }
}

static void message_ll_init(void)
{
    if(NULL == message_ll) {
        message_ll = (lv_ll_t *)lv_mem_alloc(sizeof(lv_ll_t));
        _lv_memset_00(message_ll, sizeof(lv_ll_t));
        _lv_ll_init(message_ll, sizeof(message_msg_info_t));
    }
}

static void message_ll_destory(void)
{
    message_msg_info_t * node = NULL;
    message_msg_info_t * next_node = NULL;

    if(message_ll) {
        node = (message_msg_info_t *)_lv_ll_get_head(message_ll);
        while(node) {
            //next node
            next_node = (message_msg_info_t *)_lv_ll_get_next(message_ll, node);
            if(node->name) {
                lv_mem_free(node->name);
                node->name = NULL;
            }
            if(node->data) {
                lv_mem_free(node->data);
                node->data = NULL;
            }
            _lv_ll_remove(message_ll, node);
            lv_mem_free(node);
            node = next_node;
        }
        lv_mem_free(message_ll);
        message_ll = NULL;
    }
}

static void message_ll_item_add(message_msg_info_t * info)
{
    message_msg_info_t * node = NULL;

    if(NULL == message_ll) {
        message_ll_init();
    }

    if(info) {
        node = (message_msg_info_t *)_lv_ll_ins_head(message_ll);
        _lv_memset_00(node, sizeof(message_msg_info_t));
        node->msg_source = info->msg_source;
        node->msg_index = info->msg_index;
        if(info->name) {
            node->name = (char *)lv_mem_alloc(strlen(info->name) + 1);
            _lv_memset_00(node->name, strlen(info->name) + 1);
            memcpy(node->name, info->name, strlen(info->name));
            lv_mem_free(info->name);
            info->name = NULL;
        }
        if(info->data) {
            node->data = (char *)lv_mem_alloc(strlen(info->data) + 1);
            _lv_memset_00(node->data, strlen(info->data) + 1);
            memcpy(node->data, info->data, strlen(info->data));
            lv_mem_free(info->data);
            info->data = NULL;
        }
        lv_mem_free(info);
        info = NULL;
    }
}

static void message_ll_item_del(uint32_t index)
{
    message_msg_info_t * node = NULL;
    message_msg_info_t * next_node = NULL;

    if(message_ll) {
        node = (message_msg_info_t *)_lv_ll_get_head(message_ll);
        while(node) {
            next_node = (message_msg_info_t *)_lv_ll_get_next(message_ll, node);
            if(index == node->msg_index) {
                if(node->name) {
                    lv_mem_free(node->name);
                    node->name = NULL;
                }
                if(node->data) {
                    lv_mem_free(node->data);
                    node->data = NULL;
                }
                _lv_ll_remove(message_ll, node);
                lv_mem_free(node);
                break;
            }
            node = next_node;
        }
        if(0 == message_ll_get_node_count()) {
            lv_mem_free(message_ll);
            message_ll = NULL;
        }
    } else {
        printf("%s: message list is empty!\n", __FUNCTION__);
    }
}

static uint32_t message_ll_get_node_count(void)
{
    uint32_t msg_cnt = 0;
    lv_ll_node_t * node = NULL;

    if(message_ll) {
        node = _lv_ll_get_head(message_ll);
        while(node) {
            msg_cnt++;
            node = _lv_ll_get_next(message_ll, node);
        }
    }

    return msg_cnt;
}

static message_msg_info_t * message_ll_get_item_info(uint32_t index)
{
    message_msg_info_t * node = NULL;
    message_msg_info_t * next_node = NULL;

    if(message_ll) {
        node = (message_msg_info_t *)_lv_ll_get_head(message_ll);
        while(node) {
            next_node = (message_msg_info_t *)_lv_ll_get_next(message_ll, node);
            if(index == node->msg_index) {
                break;
            }
            node = next_node;
        }
    } else {
        printf("%s: message list is empty!\n", __FUNCTION__);
    }

    return node;
}

static lv_coord_t message_get_text_length(lv_obj_t * label, char * text, lv_font_t * font)
{
    lv_coord_t letter_space = lv_obj_get_style_text_letter_space(label, LV_LABEL_PART_MAIN);
    lv_coord_t width = _lv_txt_get_width(text, strlen(text), font, letter_space, LV_TXT_FLAG_NONE);

    return width;
}

static uint32_t message_get_character_count(lv_obj_t * label, char * text, lv_font_t * font, lv_coord_t length_max)
{
    uint32_t i = 0;
    uint32_t letter = 0;
    uint32_t letter_next = 0;
    uint32_t length = strlen(text);
    lv_coord_t width = 0;
    lv_coord_t char_width = 0;
    lv_coord_t letter_space = lv_obj_get_style_text_letter_space(label, LV_LABEL_PART_MAIN);

    while(i < length) {
        letter = _lv_txt_encoded_next(text, &i);
        letter_next = _lv_txt_encoded_next(&text[i], NULL);
        char_width = lv_font_get_glyph_width(font, letter, letter_next);
        if(char_width > 0) {
            width += char_width;
            width += letter_space;
        }
        if(length_max <= width) {
            break;
        }
    }

    return (i - 1);
}

static char * message_adjust_display_data(char * data, uint32_t length)
{
    char * new_data = NULL;
    char temp_dot[] = "....";

    new_data = (char *)lv_mem_alloc(length + 1);
    _lv_memset_00(new_data, length + 1);
    strncpy(new_data, data, length - strlen(temp_dot));
    strncpy(new_data + (length - strlen(temp_dot)), temp_dot, strlen(temp_dot));

    return new_data;
}

static void message_update_ui_task_handle(lv_task_t * task)
{
    message_ui_update();
    lv_task_del(message_update_ui_task);
    message_update_ui_task = NULL;
}

#endif /*USE_LV_WATCH_MESSAGE*/
